"""
Case Type   : 资源池化集群DMS reform优化
Case Name   : 主机注入网络丢包，验证主备集具有实时一致性读能力
Create At   : 2024/05/13
Owner       : @kyleze
Description :
    1 创建测试表
    2 主机注入网络丢包故障
    3.1 循环插入数据
    3.2 主备机上同时验证时间戳

Expect      :
    1.成功
    2.1 成功
    2.2 时间戳一致
History     :
"""

import os
import unittest
from datetime import datetime

from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread

from yat.test import Node
from yat.test import macro


class DmsRform(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.dirname(__file__)} start----')
        self.com = Common()
        self.constant = Constant()
        self.primary_sh = CommonSH("PrimaryDbUser")
        self.st1_sh = CommonSH("StandbyDbUser")
        self.table_name = 't_dms_test003'
        self.pri_user_node = Node(node="PrimaryDbUser")
        self.pri_root_node = Node(node="PrimaryRoot")
        self.log.info('--获取网卡--')
        ifconfig_cmd = 'ifconfig'
        self.log.info(ifconfig_cmd)
        self.networkcard = ''
        netcard_msg = self.pri_root_node.sh(ifconfig_cmd).result()
        for netcard_item in netcard_msg.split('\n\n'):
            if self.pri_user_node.db_host in netcard_item:
                self.networkcard = netcard_item.split(":")[0].strip()
        self.log.info(self.networkcard)

    def test_dms(self):
        step = '--step1:创建测试表 expect:成功--'
        self.log.info(step)
        result = self.primary_sh.execut_db_sql(
            f"create table {self.table_name} (c1 int, c2 timestamp "
            f"default now()) with(segment=on);")
        self.log.info(result)
        self.assertIn(self.constant.CREATE_TABLE_SUCCESS,
                      result, "执行失败" + step)

        step = '--step2:主机注入网路丢包 expect:成功--'
        self.log.info(step)
        result = self.pri_root_node.sh(f"tc qdisc add dev {self.networkcard} "
                                       f"root netem loss 10%").result()
        self.log.info(result)
        self.assertIn('', result, "执行失败" + step)

        step = '--step3.1:循环插入数据 expect:成功--'
        self.log.info(step)
        cmd = f'source {macro.DB_ENV_PATH};for ((i=1;i<=10;i++)) ;' \
              f'do gsql -d {self.pri_user_node.db_name} ' \
              f'-p {self.pri_user_node.db_port} -r -c ' \
              f'"insert into {self.table_name} values($i);"; done'
        sql_thread = ComThread(self.pri_user_node.sh, args=(cmd,))
        sql_thread.setDaemon(True)
        sql_thread.start()

        step = '--step3.2:主备机上同时验证时间戳 expect:时间戳一致--'
        self.log.info(step)
        sql_cmd = f'select now() - max(c2) from {self.table_name};'
        self.log.info(sql_cmd)
        pri_thread = ComThread(self.primary_sh.execut_db_sql, args=(sql_cmd,))
        st1_thread = ComThread(self.st1_sh.execut_db_sql, args=(sql_cmd,))
        pri_thread.setDaemon(True)
        st1_thread.setDaemon(True)
        pri_thread.start()
        st1_thread.start()
        sql_thread.join(30)
        pri_thread.join(30)
        st1_thread.join(30)
        pri_result = pri_thread.get_result()
        st1_result = st1_thread.get_result()
        time_diff = \
            datetime.strptime(st1_result, "%H:%M:%S.%f") - \
            datetime.strptime(pri_result, "%H:%M:%S.%f")
        self.assertTrue(abs(time_diff.total_seconds()) < 2, "执行失败" + step)

    def tearDown(self):
        step = '----清理环境----'
        sql_res = self.primary_sh.execut_db_sql(f'drop table {self.table_name}')
        net_clean = self.pri_root_node.sh(
            f"tc qdisc del dev {self.networkcard} root netem loss 10%").result()
        self.log.info(sql_res)
        self.log.info(net_clean)
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, sql_res,
                      "执行失败" + step)
        self.assertIn('', net_clean, "执行失败" + step)
        self.log.info(f'----{os.path.dirname(__file__)} end----')
